﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net.Sockets;
using System.Threading;
using ADNDNeteworking.Netowork.MessageContainer;

namespace ADNDNetworkApplication.Network.Client
{
    public class Client
    {
        private Dictionary<int, Socket> listOfSockets;
        private TcpClient socket;
        private StringBuilder sbSentMessages;
        private string stringInput = string.Empty;

        private Thread sendThread;
        private Thread receiveThread;

        private int BUFFER_SIZE = 1024;


        public Client()
        {
            socket = new TcpClient();
            sbSentMessages = new StringBuilder();
            stringInput = string.Empty;            
        }


        public void ConnectToServer()
        {

        }

        public void ConnectToServer(string ipAddress, int port)
        {
            socket.Connect(ipAddress, port);

            sendThread = new Thread(new ParameterizedThreadStart(SendToServer));
            sendThread.Start(socket.GetStream());

            receiveThread = new Thread(new ParameterizedThreadStart(ReceivedFromServer));
            receiveThread.Start(socket.GetStream());
        }


        /// <summary>
        /// This functon will receive information
        /// </summary>
        /// <param name="param"></param>
        private void ReceivedFromServer(object param)
        {
            NetworkStream ns = (NetworkStream)param;
            bool flag = false;
            byte[] buffer = new byte[BUFFER_SIZE];
            object state = null;
            AsyncCallback callback = new AsyncCallback(readFromClient);

            while (true)
            {
                lock (ns)
                {
                    while (ns.DataAvailable)
                    {
                        ns.BeginRead(buffer, 0, BUFFER_SIZE, callback, state);
                        flag = true;
                    }
                }
                if (flag)
                {
                    flag = false;
                    string s = string.Empty;
                    //DATA IS AVAILABLE
                    for (int i = 0; i < buffer.Length; i++)
                    {
                        s += (char)buffer[i];
                    }

                    string answer = "Answer from server:" + s + Environment.NewLine;

                    System.Diagnostics.Debug.WriteLine(answer);
                    MessageBus.GetInstance().ReceiveMessage(new DNDMessage("player1",answer,"getUser",null,DateTime.Now)); 
                    /*lock (cm)
                    {
                        cm.ReceiveMessage("Answer from server:" + s + Environment.NewLine);
                    }*/
                }
            }
        }

        private void SendToServer(object param)
        {
            NetworkStream serverStream = (NetworkStream)param;

            while (!stringInput.ToLower().Contains("quit"))
            {
                if (MessageBus.GetInstance().GetLatestMessage() == null)
                {
                    Thread.Sleep(TimeSpan.FromSeconds(1));
                    continue;
                }

                //Get latest string from here...
                //byte[] outStream = System.Text.Encoding.ASCII.GetBytes(stringInput);
                byte[] outStream = System.Text.Encoding.ASCII.GetBytes(MessageBus.GetInstance().GetLatestMessage().MessageValue);
                MessageBus.GetInstance().EmptyMessageQueue();

                stringInput = string.Empty;

                lock (serverStream)
                {
                    serverStream.Write(outStream, 0, outStream.Length);
                    serverStream.Flush();
                }
            }

            serverStream.Close();
        }

        public string StringInput
        {
            set { stringInput = value; }
        }

        static void readFromClient(IAsyncResult results)
        {
            //METHOD WAS CALLED BY THE DELEGATE
        }
    }
}
